﻿/*
 * Created by SharpDevelop.
 * User: amb
 * Date: 01/06/2014
 * Time: 02:59
 * 
 * To change this template use Tools | Options | Coding | Edit Standard Headers.
 */
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Text;
using System.Windows.Forms;
using System.IO;
using System.Xml;
using JdFormsDll;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace JdForms
{
    internal class MyFormClassesGenerator
    {

        internal MyFormDecorator Decorator { get; private set; }

        internal MyFormClassesGenerator(MyFormDecorator decorator)
        {
            this.Decorator = decorator;
        }

        internal string[] Files()
        {
            try
            {
                DirectoryInfo di = new DirectoryInfo(this.Decorator.MyFormPath);
                if (!di.Exists) throw new DirectoryNotFoundException();
                FileInfo[] files = di.GetFiles();
                var f =(from FileInfo file in files 
                        where Path.GetExtension(file.FullName).ToLower() == ".jdf" 
                        select Path.GetFileNameWithoutExtension(file.Name)).ToList<string>();
                return f.ToArray();
            }
            catch { throw; }
        }

        internal string CreateCSharpClass(List<string> files, bool reflection = false)
        {
            if (files.Count == 0) return string.Empty;
            string header = Properties.Resources.HeaderCSharp;
            R(ref header, "<Date>", DateTime.Now.ToShortDateString());
            R(ref header, "<Time>", DateTime.Now.ToShortTimeString());
            R(ref header, "<namespace>", "JdFormDll.Decorator");
            if (!reflection)
            {
                R(ref header, "<reflection>", string.Empty);
                R(ref header, "<assembly>", string.Empty);    
            }
            else
            {
                string r = "using System.Reflection;\r\n";
                r += "using System.Runtime.InteropServices;\r\n\r\n";
                r += string.Format("[assembly: AssemblyVersion(\"1.{0:0000}.{1:0000}.{2:0000}\")]\r\n", DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day);
                r += string.Format("[assembly: AssemblyFileVersion(\"1.{0:0000}.{1:0000}.{2:0000}\")]\r\n", DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day);
                r += "[assembly: AssemblyCompany(\"John Doe\")]\r\n";
                r += string.Format("[assembly: AssemblyCopyright(\"Copyright {0}\")]\r\n", DateTime.Now.Year);
                r += "[assembly: AssemblyDescription(\"MyForm Decorator Repository\")]\r\n";
                r += "[assembly: AssemblyTrademark(\"(C) John Doe\")]\r\n";
                r += "[assembly: ComVisible(false)]\r\n";
                R(ref header, "<reflection>", r);
            }
            string comma = string.Empty;
            string value = string.Empty;
            int Index = 0;
            List<MyFormProperties> properties = new List<MyFormProperties>();
            foreach (string file in files)
            {
                string f = Path.Combine(this.Decorator.MyFormPath, file.Trim() + ".jdf");
                properties.Add(new MyFormProperties(f, this.Decorator));
                value += comma + "\t\t" + file.Trim().Replace(" ", "_").Trim() + string.Format(" = {0}", Index);
                comma = ",\r\n";
                ++Index;
            }
            R(ref header, "<files>", value);
            R(ref header, "<class>", "Skins");

            StringBuilder prop = new StringBuilder ();
            prop.Append(this.CreateProperty("BackColor"));
            prop.Append(this.CreateProperty("BackColorShadow"));
            prop.Append(this.CreateProperty("BorderColor"));
            prop.Append(this.CreateProperty("TextCaptionColor"));
            prop.Append(this.CreateProperty("TextCaptionColorShadow"));
            prop.Append(this.CreateProperty("ForeColor"));
            prop.Append(this.CreateProperty("BorderStyle"));
            prop.Append(this.CreateProperty("CaptionBorderRoundPercent"));
            prop.Append(this.CreateProperty("ColorsDifferencePercent"));
            prop.Append(this.CreateProperty("TextCaptionAlignment"));
            prop.Append(this.CreateProperty("TextCaptionShadow"));
            prop.Append(this.CreateProperty("IsResizable"));
            prop.Append(this.CreateProperty("IsMoveable"));
            prop.Append(this.CreateProperty("ShowClientBorder"));
            prop.Append(this.CreateProperty("ShowCaptionBorder"));
            prop.Append(this.CreateProperty("ShowTooltip"));
            prop.Append(this.CreateProperty("TextCaptionFont",false));
			R(ref header,"<property>",prop.ToString());
            
            StringBuilder body = new StringBuilder();

            List<Color> colors = (from MyFormProperties p in properties select p.BackColor).ToList<Color>();
            body.Append(this.CreateColors("Color", "BackColor", colors));
            colors = (from MyFormProperties p in properties select p.BackColorShadow).ToList<Color>();
            body.Append(this.CreateColors("Color", "BackColorShadow", colors));
            colors = (from MyFormProperties p in properties select p.BorderColor).ToList<Color>();
            body.Append(this.CreateColors("Color", "BorderColor", colors));
            colors = (from MyFormProperties p in properties select p.TextCaptionColor).ToList<Color>();
            body.Append(this.CreateColors("Color", "TextCaptionColor", colors));
            colors = (from MyFormProperties p in properties select p.TextCaptionColorShadow).ToList<Color>();
            body.Append(this.CreateColors("Color", "TextCaptionColorShadow", colors));
            colors = (from MyFormProperties p in properties select p.ForeColor).ToList<Color>();
            body.Append(this.CreateColors("Color", "ForeColor", colors));
            List<Border3DStyle> borders = (from MyFormProperties p in properties select p.BorderStyle).ToList<Border3DStyle>();
            body.Append(this.CreateBorder("Border3DStyle", "BorderStyle", borders));
            List<Percent> perc = (from MyFormProperties p in properties select p.CaptionBorderRoundPercent).ToList<Percent>();
            body.Append(this.CreatePercent("Percent", "CaptionBorderRoundPercent", perc));
            perc = (from MyFormProperties p in properties select p.ColorsDifferencePercent).ToList<Percent>();
            body.Append(this.CreatePercent("Percent", "ColorsDifferencePercent", perc));
            List<ContentAlignment> align = (from MyFormProperties p in properties select p.TextCaptionAlignment).ToList<ContentAlignment>();
            body.Append(this.CreateAlignment("ContentAlignment", "TextCaptionAlignment", align));
            List<Shadow> shadows = (from MyFormProperties p in properties select p.TextCaptionShadow).ToList<Shadow>();
            body.Append(this.CreateShadow("Shadow", "TextCaptionShadow", shadows));
            List<bool> b = (from MyFormProperties p in properties select p.IsResizable).ToList<bool>();
            body.Append(this.Createbool("bool", "IsResizable", b));
            b = (from MyFormProperties p in properties select p.IsMoveable).ToList<bool>();
            body.Append(this.Createbool("bool", "IsMoveable", b));
            b = (from MyFormProperties p in properties select p.ShowClientBorder).ToList<bool>();
            body.Append(this.Createbool("bool", "ShowClientBorder", b));
            b = (from MyFormProperties p in properties select p.ShowCaptionBorder).ToList<bool>();
            body.Append(this.Createbool("bool", "ShowCaptionBorder", b));
            b = (from MyFormProperties p in properties select p.ShowTooltip).ToList<bool>();
            body.Append(this.Createbool("bool", "ShowTooltip", b));
            List<Font> fonts = (from MyFormProperties p in properties select p.TextCaptionFont).ToList<Font>();
            body.Append(this.CreateFont("Font", "TextCaptionFont", fonts));
            R(ref header, "<body>", body.ToString());
            if (!reflection) R(ref header, "<access>", "internal");
            else R(ref header, "<access>", "public");
            return header;
        }

        internal string CreateVBClass(List<string> files)
        {
            if (files.Count == 0) return string.Empty;
            string header = Properties.Resources.HeaderVB;
            R(ref header, "<Date>", DateTime.Now.ToShortDateString());
            R(ref header, "<Time>", DateTime.Now.ToShortTimeString());
            R(ref header, "<namespace>", "JdFormDll.Decorator");
            string comma = string.Empty;
            string value = string.Empty;
            int Index = 0;
            List<MyFormProperties> properties = new List<MyFormProperties>();
            foreach (string file in files)
            {
                string f = Path.Combine(this.Decorator.MyFormPath, file.Trim() + ".jdf");
                properties.Add(new MyFormProperties(f, this.Decorator));
                value += comma + "\t\t" + file.Trim().Replace(" ", "_").Trim() + string.Format(" = {0}", Index);
                comma = "\r\n";
                ++Index;
            }
            R(ref header, "<files>", value);
            R(ref header, "<class>", "Skins");
            
            StringBuilder prop = new StringBuilder ();
            prop.Append(this.CreateProperty("BackColor",true,true));
            prop.Append(this.CreateProperty("BackColorShadow",true,true));
            prop.Append(this.CreateProperty("BorderColor",true,true));
            prop.Append(this.CreateProperty("TextCaptionColor",true,true));
            prop.Append(this.CreateProperty("TextCaptionColorShadow",true,true));
            prop.Append(this.CreateProperty("ForeColor",true,true));
            prop.Append(this.CreateProperty("BorderStyle",true,true));
            prop.Append(this.CreateProperty("CaptionBorderRoundPercent",true,true));
            prop.Append(this.CreateProperty("ColorsDifferencePercent",true,true));
            prop.Append(this.CreateProperty("TextCaptionAlignment",true,true));
            prop.Append(this.CreateProperty("TextCaptionShadow",true,true));
            prop.Append(this.CreateProperty("IsResizable",true,true));
            prop.Append(this.CreateProperty("IsMoveable",true,true));
            prop.Append(this.CreateProperty("ShowClientBorder",true,true));
            prop.Append(this.CreateProperty("ShowCaptionBorder",true,true));
            prop.Append(this.CreateProperty("ShowTooltip",true,true));
            prop.Append(this.CreateProperty("TextCaptionFont",false,true));
			R(ref header,"<property>",prop.ToString());

            StringBuilder body = new StringBuilder();

            List<Color> colors = (from MyFormProperties p in properties select p.BackColor).ToList<Color>();
            body.Append(this.CreateColors("Color", "BackColor", colors, true));
            colors = (from MyFormProperties p in properties select p.BackColorShadow).ToList<Color>();
            body.Append(this.CreateColors("Color", "BackColorShadow", colors, true));
            colors = (from MyFormProperties p in properties select p.BorderColor).ToList<Color>();
            body.Append(this.CreateColors("Color", "BorderColor", colors, true));
            colors = (from MyFormProperties p in properties select p.TextCaptionColor).ToList<Color>();
            body.Append(this.CreateColors("Color", "TextCaptionColor", colors, true));
            colors = (from MyFormProperties p in properties select p.TextCaptionColorShadow).ToList<Color>();
            body.Append(this.CreateColors("Color", "TextCaptionColorShadow", colors, true));
            colors = (from MyFormProperties p in properties select p.ForeColor).ToList<Color>();
            body.Append(this.CreateColors("Color", "ForeColor", colors, true));
            List<Border3DStyle> borders = (from MyFormProperties p in properties select p.BorderStyle).ToList<Border3DStyle>();
            body.Append(this.CreateBorder("Border3DStyle", "BorderStyle", borders, true));
            List<Percent> perc = (from MyFormProperties p in properties select p.CaptionBorderRoundPercent).ToList<Percent>();
            body.Append(this.CreatePercent("Percent", "CaptionBorderRoundPercent", perc, true));
            perc = (from MyFormProperties p in properties select p.ColorsDifferencePercent).ToList<Percent>();
            body.Append(this.CreatePercent("Percent", "ColorsDifferencePercent", perc, true));
            List<ContentAlignment> align = (from MyFormProperties p in properties select p.TextCaptionAlignment).ToList<ContentAlignment>();
            body.Append(this.CreateAlignment("ContentAlignment", "TextCaptionAlignment", align, true));
            List<Shadow> shadows = (from MyFormProperties p in properties select p.TextCaptionShadow).ToList<Shadow>();
            body.Append(this.CreateShadow("Shadow", "TextCaptionShadow", shadows, true));
            List<bool> b = (from MyFormProperties p in properties select p.IsResizable).ToList<bool>();
            body.Append(this.Createbool("Boolean", "IsResizable", b, true));
            b = (from MyFormProperties p in properties select p.IsMoveable).ToList<bool>();
            body.Append(this.Createbool("Boolean", "IsMoveable", b, true));
            b = (from MyFormProperties p in properties select p.ShowClientBorder).ToList<bool>();
            body.Append(this.Createbool("Boolean", "ShowClientBorder", b, true));
            b = (from MyFormProperties p in properties select p.ShowCaptionBorder).ToList<bool>();
            body.Append(this.Createbool("Boolean", "ShowCaptionBorder", b, true));
            b = (from MyFormProperties p in properties select p.ShowTooltip).ToList<bool>();
            body.Append(this.Createbool("Boolean", "ShowTooltip", b, true));
            List<Font> fonts = (from MyFormProperties p in properties select p.TextCaptionFont).ToList<Font>();
            body.Append(this.CreateFont("Font", "TextCaptionFont", fonts, true));
            R(ref header, "<body>", body.ToString());
            return header;
        }

        private string CreateProperty(string name,bool rn = true, bool isvb = false)
        {
        	string format =	"\t\t\tForm.<name> = <name>;";
        	if(isvb) format = "\t\t\tForm.<name> = <name>";
        	if(rn) format += "\r\n";
        	return format.Replace("<name>",name);
        }
        
        private string CreateFont(string type, string property, List<Font> fonts, bool isvb = false)
        {
            string value = string.Empty;
            string comma = string.Empty;
            string temp = Properties.Resources.BodyCSharp;
            string format = "\t\t\tnew Font(\"{0}\",{1}f,{2})";
            if (isvb)
            {
                temp = Properties.Resources.BodyVB;
                format = "\t\t\tNew Font(\"{0}\",{1}F,{2})";
            }
            R(ref temp, "<type>", type);
            R(ref temp, "<property>", property);
            foreach (var font in fonts)
            {
                string[] v = font.Style.ToString().Split(new string[] { "," }, StringSplitOptions.None);
                string b = string.Empty;
                string style = string.Empty;
                foreach (string s in v)
                {
                    style += b + string.Format("FontStyle.{0}", s.Trim());
                    b = " | ";
                    if (isvb) b = " Or ";
                }
                value += comma + string.Format(format, font.Name, font.Size.ToString().Replace(",", "."), style);
                comma = ",\r\n";
            }
            R(ref temp, "<values>", value);
            return temp;
        }

        private string Createbool(string type, string property, List<bool> bools, bool isvb = false)
        {
            string value = string.Empty;
            string comma = string.Empty;
            string temp = Properties.Resources.BodyCSharp;
            string format = "\t\t\t{0}";
            if (isvb)
            {
                temp = Properties.Resources.BodyVB;
                format = "\t\t\t{0}";
            }
            R(ref temp, "<type>", type);
            R(ref temp, "<property>", property);
            foreach (var b in bools)
            {
                string v = b.ToString();
                if (!isvb) { v = v.ToLower(); }
                value += comma + string.Format(format, v);
                comma = ",\r\n";
            }
            R(ref temp, "<values>", value);
            return temp;
        }

        private string CreateShadow(string type, string property, List<Shadow> shadows, bool isvb = false)
        {
            string value = string.Empty;
            string comma = string.Empty;
            string temp = Properties.Resources.BodyCSharp;
            if (isvb) temp = Properties.Resources.BodyVB;
            R(ref temp, "<type>", type);
            R(ref temp, "<property>", property);
            string format = "\t\t\tShadow.{0}";
            if (isvb) format = "\t\t\tShadow.{0}";
            foreach (var shadow in shadows)
            {
                
                value += comma + string.Format(format, shadow);
                comma = ",\r\n";
            }
            R(ref temp, "<values>", value);
            return temp;
        }

        private string CreateAlignment(string type, string property, List<ContentAlignment> alignments, bool isvb = false)
        {
            string value = string.Empty;
            string comma = string.Empty;
            string temp = Properties.Resources.BodyCSharp;
            if (isvb) temp = Properties.Resources.BodyVB;
            R(ref temp, "<type>", type);
            R(ref temp, "<property>", property);
            string format = "\t\t\tContentAlignment.{0}";
            if (isvb) format = "\t\t\tContentAlignment.{0}";
            foreach (var alignment in alignments)
            {
                value += comma + string.Format(format, alignment);
                comma = ",\r\n";
            }
            R(ref temp, "<values>", value);
            return temp;
        }

        private string CreatePercent(string type, string property, List<Percent> borders, bool isvb = false)
        {
            string value = string.Empty;
            string comma = string.Empty;
            string temp = Properties.Resources.BodyCSharp;
            string format = "\t\t\tPercent.{0}";
            if (isvb)
            {
                temp = Properties.Resources.BodyVB;
                format = "\t\t\tPercent.{0}";
            }
            R(ref temp, "<type>", type);
            R(ref temp, "<property>", property);
            foreach (var border in borders)
            {
                value += comma + string.Format(format, border);
                comma = ",\r\n";
            }
            R(ref temp, "<values>", value);
            return temp;
        }

        private string CreateBorder(string type, string property, List<Border3DStyle> borders, bool isvb = false)
        {
            string value = string.Empty;
            string comma = string.Empty;
            string temp = Properties.Resources.BodyCSharp;
            string format = "\t\t\tBorder3DStyle.{0}";
            if (isvb)
            {
                temp = Properties.Resources.BodyVB;
                format = "\t\t\tBorder3DStyle.{0}";
            }
            R(ref temp, "<type>", type);
            R(ref temp, "<property>", property);
            foreach (var border in borders)
            {
                value += comma + string.Format(format, border);
                comma = ",\r\n";
            }
            R(ref temp, "<values>", value);
            return temp;
        }


        private string CreateColors(string type, string property, List<Color> colors, bool isvb = false)
        {
            string value = string.Empty;
            string comma = string.Empty;
            string temp = Properties.Resources.BodyCSharp;
            string format ="\t\t\tColor.FromArgb({0},{1},{2},{3})";
            if (isvb)
            {
                temp = Properties.Resources.BodyVB;
                format = "\t\t\tColor.FromArgb({0},{1},{2},{3})";
            }
            R(ref temp, "<type>", type);
            R(ref temp, "<property>", property);
            foreach (var color in colors)
            {
                value += comma + string.Format(format, color.A, color.R, color.G, color.B);
                comma = ",\r\n";
            }
            R(ref temp, "<values>", value);
            return temp;
        }

        private void R(ref string str, string from, string to)
        {
            str = str.Replace(from, to);
        }
    }
}
